package com.itheima.consumer.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 消息异常处理配置类
 *
 * @author 张文接
 * @version 1.0
 * @createTime 2024/9/20 10:14
 */
@Configuration
public class ErrorMessageConfig {

    /**
     * 创建一个名为 "error.direct" 的 DirectExchange。
     *
     * @return 返回创建成功的DirectExchange对象
     */
    @Bean
    public DirectExchange errorMessageExchange() {
        return new DirectExchange("error.direct");
    }

    /**
     * 创建一个名为 "error.queue" 的持久化队列
     *
     * @return 返回创建成功的持久化队列对象
     */
    @Bean
    public Queue errorQueue() {
        return new Queue("error.queue", true);
    }

    /**
     * 将名称为"error.queue"的队列绑定到名为"error.direct"的 DirectExchange。
     * 此绑定使用路由键"error"进行消息路由，即来自"error.direct"的消息，其路由键为"error"，将被路由到"error.queue"。
     *
     * @param errorQueue           要绑定的队列。
     * @param errorMessageExchange 要绑定的 DirectExchange。
     * @return 返回创建的 Binding 对象。
     */
    @Bean
    public Binding errorBinding(Queue errorQueue, DirectExchange errorMessageExchange) {
        return BindingBuilder.bind(errorQueue).to(errorMessageExchange).with("error");
    }

    /**
     * 创建一个消息恢复器，用于在消息处理失败时重新发布消息到指定的交换器和路由键
     * @param rabbitTemplate RabbitTemplate对象，用于重新发布消息
     * @return 返回创建的MessageRecoverer对象
     */
    @Bean
    public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate) {
        return new RepublishMessageRecoverer(rabbitTemplate, "error.direct", "error");
    }
}
